home *** CD-ROM | disk | FTP | other *** search
- /* GRAPHIC LISP */
- /* Scritto nel 1991-94 da Zoia Andrea Michele */
- /* Via Pergola #1 Tirano (SO) Tel. 0342-704210 */
- /* file clos_lf1.c */
-
- #include "clos.h"
-
-
- /* funzioni principali ********************************/
- /* CAR , CDR , CONS , QUOTE , EVAL , COND */
- /* SETF , SET , APPEND , LIST , LAST , ELT */
- /* REVERSE , LENGHT , FUNCTION , PLIST */
- /* DEFVAR , DEFUN , DEFMACRO , BACKQUOTE , NAME2STR */
- /******************************************************/
-
- /* nota:************************/
- /* SETQ è tradotta in SETF */
- /* FIRST è tradotta in CAR */
- /* REST è tradotta in CDR */
- /*******************************/
-
- void aux_set_setf();
-
- void lf_car LF_PARAMS
- {
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- if(IS_CONS(nin)){
- nout->node=nin;
- nout->type=P_CONSLEFT;
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_cdr LF_PARAMS
- {
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- if(IS_CONS(nin)){
- nout->node=nin;
- nout->type=P_CONSRIGHT;
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_cons LF_PARAMS
- {
- node n;
- node e=nin;
-
- TYPE(n=node_make())|=NT_IS_CONS;
- CONSLEFT(n)=CONSRIGHT(n)=NIL;
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- CONSLEFT(n)=calc_pointer(nout);
- if(IS_CONS(nin=CONSRIGHT(nin))){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- CONSRIGHT(n)=calc_pointer(nout);
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&e);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&e);
- }
-
- void lf_quote LF_PARAMS
- {
- if(IS_CONS(nin)){
- nout->node=CONSLEFT(nin);
- nout->type=P_ALLNODE;
- return;
- }
- error(E_FEWARGS,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&nin);
- }
-
- void lf_eval LF_PARAMS
- {
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- eval(calc_pointer(nout),nout,genv,lenv,fl);
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_cond LF_PARAMS
- {
- node n;
- /* syntax (COND ( test oksx*)*) */
- /* nin=( ( test oksx*)* ) */
-
- while(IS_CONS(nin)){
- n=CONSLEFT(nin); /* n= (test oksx*) */
- if(IS_CONS(n)){
- eval(CONSLEFT(n),nout,genv,lenv,EVAL_NORM);
- if(calc_pointer(nout)!=NIL){ /* nout=EVAL(test) */
- n=CONSRIGHT(n); /* n= (oksx*) */
- if(!IS_CONS(n)){
- nout->node=NIL;
- nout->type=P_ALLNODE;
- return;
- }
- while(IS_CONS(CONSRIGHT(n))){
- eval(CONSLEFT(n),nout,genv,lenv,EVAL_NORM);
- n=CONSRIGHT(n);
- }
- eval(CONSLEFT(n),nout,genv,lenv,fl);
- return;
- }
- nin=CONSRIGHT(nin); /* nin=next test */
- continue;
- }
- /* else n=sx */
- eval(n,nout,genv,lenv,fl);
- if(calc_pointer(nout)!=NIL)return;
- nin=CONSRIGHT(nin);
- continue;
- }
- nout->type=P_ALLNODE;
- nout->node=NIL;
- }
-
- void aux_set_setf (nin,nout,genv,lenv,fl,dbleval)
- node nin;
- node_p *nout;
- node genv;
- node lenv;
- unsigned fl;
- int dbleval;
- {
- /* sintassi (SETF { n v }+) */
- /* assegna al legame e(n) il valore e(v) */
-
- node_p tmpp;
- node t=nin;
-
- if(nin==NIL)
- error(E_FEWARGS,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&NIL);
-
- while(nin!=NIL){
- if(IS_CONS(nin)){
- /* il flag EVAL_SETF costringe eval a non causare l'errore */
- /* UNBOUND ATOM ... se non c'e' nulla attaccato al nome */
- /* valutato, ed eval ritornerà in ogni caso il legame che */
- /* verrà poi collegato */
- if(dbleval){
- eval(CONSLEFT(nin),nout,genv,lenv,fl);
- eval(calc_pointer(nout),&tmpp,genv,lenv,EVAL_SETF);
- }else{
- eval(CONSLEFT(nin),&tmpp,genv,lenv,EVAL_SETF);
- }
- nin=CONSRIGHT(nin);
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- switch(tmpp.type){
- case P_VALUE:
- VALUE(tmpp.node)=calc_pointer(nout);
- break;
- case P_FUNC:
- FUNCTION(tmpp.node)=calc_pointer(nout);
- break;
- case P_PLIST:
- PLIST(tmpp.node)=calc_pointer(nout);
- break;
- case P_CONSLEFT:
- CONSLEFT(tmpp.node)=calc_pointer(nout);
- break;
- case P_CONSRIGHT:
- CONSRIGHT(tmpp.node)=calc_pointer(nout);
- break;
- case P_UNBOUNDVALUE:
- /* eval(col flag EVAL_SETF) ritorna P_UNBOUNDxxxx */
- /* riferito al legame del nodo che non aveva valore */
- /* al posto di causare un errore */
- VALUE(tmpp.node)=calc_pointer(nout);
- TYPE(tmpp.node)|=NT_HAS_VALUE;
- break;
- case P_UNBOUNDFUNC:
- FUNCTION(tmpp.node)=calc_pointer(nout);
- TYPE(tmpp.node)|=NT_HAS_FUNCTION;
- break;
- case P_UNBOUNDPLIST:
- PLIST(tmpp.node)=calc_pointer(nout);
- TYPE(tmpp.node)|=NT_HAS_PLIST;
- break;
- case P_ALLNODE:
- /* non si puo' assegnare nulla ad un legame */
- /* imprecisato come P_ALLNODE */
- /* ad.es se si fa (setf 12 34) */
- error(E_BADARGS,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&tmpp.node);
- default:
- error(E_BADSETF,ERR_TCRIT|ERR_MINTERNAL|ERR_PVOID,NULL);
- }
- }
- else{
- error(nin==NIL?E_FEWARGS:E_BADLIST,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&t);
- }
- }
- else{
- error(nin==NIL?E_FEWARGS:E_BADLIST,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&t);
- }
- nin=CONSRIGHT(nin);
- }
- }
-
-
- void lf_set LF_PARAMS
- {
- /* sintassi (set (nome valore)* ) */
- /* NB: ''nome,, viene valutato 2 volte */
- aux_set_setf(nin,nout,genv,lenv,fl,1);
- }
-
- void lf_setf LF_PARAMS
- {
- /* sintassi (setf (nome valore)* ) */
- /* NB: ''nome,, viene valutato 1 volta */
- aux_set_setf(nin,nout,genv,lenv,fl,0);
- }
-
- void lf_list LF_PARAMS
- {
- nout->node=eval_list(nin,genv,lenv);
- nout->type=P_ALLNODE;
- }
-
- void lf_nconc LF_PARAMS
- {
- node list=eval_list(nin,genv,lenv);
- node prevcons=NIL;
- node elm;
-
- nout->node=NIL;
- nout->type=P_ALLNODE;
- while(IS_CONS(list)){
- elm=CONSLEFT(list);
- if(nout->node==NIL)nout->node=elm;
- if(elm!=NIL){
- if(!IS_CONS(elm))error(E_BADARGS,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&elm);
- if(prevcons!=NIL)CONSRIGHT(prevcons)=elm;
- do{
- prevcons=elm;
- elm=CONSRIGHT(elm);
- }while(IS_CONS(elm));
- }
- list=CONSRIGHT(list);
- }
- }
-
- void lf_append LF_PARAMS
- {
- node list=eval_list(nin,genv,lenv);
- node prevcons=NIL;
- node elm;
-
- nout->node=NIL;
- nout->type=P_ALLNODE;
- while(IS_CONS(list)){
- elm=list_dup(CONSLEFT(list));
- if(nout->node==NIL)nout->node=elm;
- if(elm!=NIL){
- if(!IS_CONS(elm))error(E_BADARGS,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&elm);
- if(prevcons!=NIL)CONSRIGHT(prevcons)=elm;
- do{
- prevcons=elm;
- elm=CONSRIGHT(elm);
- }while(IS_CONS(elm));
- }
- list=CONSRIGHT(list);
- }
- }
-
- void lf_last LF_PARAMS
- {
- node var;
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- var=calc_pointer(nout);
- if(IS_CONS(var)){
- while(IS_CONS(CONSRIGHT(var)))
- var=CONSRIGHT(var);
- nout->node=var;
- nout->type=P_CONSLEFT;
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&var);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void lf_elt LF_PARAMS
- {
- node list;
- node n=nin;
- n_int counter;
-
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- list=calc_pointer(nout);
- if(!IS_CONS(list))error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&list);
- nin=CONSRIGHT(nin);
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- if(GET_NTYPE(nin)==NT_IS_VALUE && GET_VTYPE(nin)==NT_INTEGER){
- if((counter=INTEGER(nin))>0){
- while(--counter){
- if(IS_CONS(list))
- list=CONSRIGHT(list);
- else
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNINT,&INTEGER(nin));
- }
- if(IS_CONS(list)){
- nout->type=P_CONSLEFT;
- nout->node=list;
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNINT,&INTEGER(nin));
- }
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&n);
- }
-
-
-
- void lf_reverse LF_PARAMS
- {
- int i;
- char *b=buf1;
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- if(IS_VALUE(nin)&&GET_VTYPE(nin)==NT_STRING){
- string_get(STRING(nin),b);
- i=strlen(b);
- buf2[i]=0;
- while(i--){
- buf2[i]=*b++;
- }
- TYPE(nout->node=node_make())|=NT_IS_VALUE+NT_STRING;
- STRING(nout->node)=string_put(buf2,nout->node);
- nout->type=P_ALLNODE;
- return;
- }
- nout->type=P_ALLNODE;
- nout->node=NIL;
- while(IS_CONS(nin)){
- TYPE(genv=node_make())|=NT_IS_CONS;
- CONSLEFT(genv)=CONSLEFT(nin);
- CONSRIGHT(genv)=nout->node;
- nout->node=genv;
- nin=CONSRIGHT(nin);
- }
- return;
- }
- error(E_BADLIST,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
- void lf_lenght LF_PARAMS
- {
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- nout->type=P_ALLNODE;
- if(IS_CONS(nin) || nin==NIL){
- TYPE(nout->node=node_make())|=NT_IS_VALUE+NT_INTEGER;
- INTEGER(nout->node)=(n_int)listlen_func(nin);
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
-
-
- void lf_function LF_PARAMS
- {
- /* sintassi (function nome) oppure #'nome */
- /* ritorna un puntatore al legame funzionale del nodo-argomento */
- /* se il nome non è un simbolo allora lo si valuta*/
- if(IS_CONS(nin)){
- nout->node=nin=CONSLEFT(nin);
- if(!IS_NAME(nin)){
- eval(nin,nout,genv,lenv,EVAL_SETF);
- if(!IS_NAME(nout->node))
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nout->node);
- }
- if( HAS_FUNCTION(nout->node) ){
- nout->type=P_FUNC;
- return;
- }
- if(fl==EVAL_SETF){
- nout->type=P_UNBOUNDFUNC;
- return;
- }
- error(E_UNBOUNDFUNC,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
-
- void lf_plist LF_PARAMS
- {
- /* ritorna un puntatore al legame plist del nodo-argomento */
- if(IS_CONS(nin)){
- if(IS_NAME(CONSLEFT(nin))){
- nout->node=CONSLEFT(nin);
- }else{
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nout->node=calc_pointer(nout);
- if(!IS_NAME(nout->node))
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nout->node);
- }
- if( HAS_PLIST(nout->node) ){
- nout->type=P_PLIST;
- return;
- }
- if(fl==EVAL_SETF){
- nout->type=P_UNBOUNDPLIST;
- return;
- }
- nout->node=node_alloc(UNBOUND_ID);
- nout->type=P_ALLNODE;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_defvar LF_PARAMS
- {
- node name;
-
- /* sintassi (defvar {nome valore}+) */
-
- if(IS_CONS(nin)){
- while(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_SETF);
- if(IS_NAME(nout->node)){
- name=nout->node;
- nin=CONSRIGHT(nin);
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=CONSRIGHT(nin);
- }else{
- nout->type=P_ALLNODE;
- nout->node=NIL;
- }
- if(HAS_BIND(name)){
- nout->node=NIL;
- nout->type=P_ALLNODE;
- }else{
- TYPE(name)|=NT_HAS_BIND;
- TYPE(name)&=(~NT_HAS_VALUE);
- VALUE(name)=calc_pointer(nout);
- }
- }else{
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nout->node);
- }
- }
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
-
-
- void lf_defun LF_PARAMS
- {
- node fn;
-
- /* sintassi (defun nome <lambda-form>) */
- /* se nome non è un simbolo allora lo si valuta */
-
- if(IS_CONS(nin)){
- fn=CONSLEFT(nin);
- if(!IS_NAME(fn)){
- eval(fn,nout,genv,lenv,EVAL_SETF);
- if(!IS_NAME(nout->node))
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nout->node);
- fn=nout->node;
- }
- lf_lambda(CONSRIGHT(nin),nout,genv,lenv,EVAL_NORM);
- TYPE(fn)|=NT_HAS_FUNCTION;
- FUNCTION(fn)=FUNCTION(nout->node);
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_defmacro LF_PARAMS
- {
- node fn;
-
- /* sintassi (defmacro nome <lambda-form>) */
- /* se nome non è un simbolo allora lo si valuta */
-
- if(IS_CONS(nin)){
- fn=CONSLEFT(nin);
- if(!IS_NAME(fn)){
- eval(fn,nout,genv,lenv,EVAL_SETF);
- if(!IS_NAME(nout->node))
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nout->node);
- fn=nout->node;
- }
- lf_lambda(CONSRIGHT(nin),nout,genv,lenv,EVAL_NORM);
- TYPE(fn)|=NT_HAS_FUNCTION;
- FUNCTION(fn)=FUNCTION(nout->node);
- TYPE(FUNCTION(fn))=NT_IS_VALUE+NT_MACRO;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- node Coma,Genv,Lenv;
- node_p Nout;
-
- void backquote_scan_element();
-
-
- void lf_backquote LF_PARAMS
- {
- /* sintassi (backquote ( s-espressioni) ) */
-
- node last=NIL;
-
- Coma=node_alloc("COMA");
- Genv=genv;
- Lenv=lenv;
- if(IS_CONS(nin)){
- if(IS_CONS(nin=CONSLEFT(nin))){
- while(IS_CONS(nin)){
- if(last==NIL){
- last=nout->node=node_make();
- }else{
- CONSRIGHT(last)=node_make();
- last=CONSRIGHT(last);
- }
- TYPE(last)|=NT_IS_CONS;
- CONSLEFT(last)=CONSRIGHT(last)=NIL;
- backquote_scan_element(CONSLEFT(nin),&CONSLEFT(last));
- nin=CONSRIGHT(nin);
- }
- nout->type=P_ALLNODE;
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void backquote_scan_element(el,where)
- node el;
- node *where;
- {
- if(IS_CONS(el)){
- if(CONSLEFT(el)==Coma){
- if(IS_CONS(el))
- el=CONSRIGHT(el);
- eval(CONSLEFT(el),&Nout,Genv,Lenv,EVAL_NORM);
- *where=calc_pointer(&Nout);
- return;
- }
- TYPE(*where=node_make())|=NT_IS_CONS;
- CONSLEFT(*where)=NIL;
- CONSRIGHT(*where)=NIL;
- backquote_scan_element(CONSLEFT(el),&CONSLEFT(*where));
- backquote_scan_element(CONSRIGHT(el),&CONSRIGHT(*where));
- return;
- }
- *where=el;
- }
-
-
-
-
- void lf_name2str LF_PARAMS
- {
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- if(IS_NAME(nin)){
- nout->node=node_make();
- STRING(nout->node)=string_put(string_get(NAME(nin),buf1),nout->node);
- TYPE(nout->node)|=NT_IS_VALUE+NT_STRING;
- nout->type=P_ALLNODE;
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-